#!/usr/bin/env python
# -*- coding:utf-8 -*-

import ctypes

BYTE = ctypes.c_ubyte
WORD = ctypes.c_ushort
DWORD = ctypes.c_ulong
LPBYTE = ctypes.POINTER(ctypes.c_ubyte)
LPTSTR = ctypes.POINTER(ctypes.c_char)
HANDLE = ctypes.c_void_p
PVOID = ctypes.c_void_p
LPVOID = ctypes.c_void_p
UINT_PTR = ctypes.c_ulong
SIZE_T = ctypes.c_ulong
DWORD64 = ctypes.c_ulonglong
CHAR = ctypes.c_char
ARCH_AMD64 = "amd64"
#常量
DEBUG_PROCESS = 0x00000001
DEBUG_ONLY_THIS_PROCESS = 0x00000002
CREATE_SUSPENDED = 0x00000004
CREATE_NEW_CONSOLE = 0x00000010
PROCESS_ALL_ACCESS = 0x001F0FFF
INFINITE = 0xFFFFFFFF
DBG_CONTINUE = 0x00010002

DBG_EXCEPTION_NOT_HANDLED = 0x80010001
#调试事件
EXCEPTION_DEBUG_EVENT = 0x1
CREATE_THREAD_DEBUG_EVENT = 0x2
CREATE_PROCESS_DEBUG_EVENT = 0x3
EXIT_THREAD_DEBUG_EVENT = 0x4
EXIT_PROCESS_DEBUG_EVENT = 0x5
LOAD_DLL_DEBUG_EVENT = 0x6
UNLOAD_DLL_DEBUG_EVENT = 0x7
OUTPUT_DEBUG_STRING_EVENT = 0x8
RIP_EVENT = 0x9

#异常代码
EXCEPTION_ACCESS_VIOLATION = 0xC0000005
EXCEPTION_BREAKPOINT = 0x80000003
EXCEPTION_GUARD_PAGE = 0x80000001
EXCEPTION_SINGLE_STEP =0x80000004
STATUS_WX86_BREAKPOINT = 0x4000001F
STATUS_WX86_SINGLE_STEP = 0x4000001E

#CreateToolhelp32Snapshot()中的线程常量
#CreateToolhelp32Snapshot()获取系统中全部进程的快照
TH32CS_SNAPHEAPLIST = 0x00000001
TH32CS_SNAPPROCESS = 0x00000002
TH32CS_SNAPTHREAD = 0x00000004
TH32CS_SNAPMODULE = 0x00000008
TH32CS_INHERIT = 0x80000000
TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
THREAD_ALL_ACCESS = 0x001F03FF
THREAD_ALL_ACCESS64 =(0x0400 | 0x0010 | 0x0020 | 0x0008 | 0x0002 | 0x0040 | 0x0800)
#GetThreadContext()上下文标志
#GetThreadContext()获取指线程的上下文,寄存器内容
CONTEXT_FULL = 0x00010007
CONTEXT_DEBUG_REGISTERS = 0x00010010
#x64
CONTEXT_AMD64 = 0x00100000
CONTEXT_CONTROL = (CONTEXT_AMD64 | 0x00000001)
CONTEXT_INTEGER = (CONTEXT_AMD64 | 0x00000002)
CONTEXT_SEGMENTS = (CONTEXT_AMD64 | 0x00000004)
CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | 0x00000008)
CONTEXT_DEBUG_REGISTERS_64 = (CONTEXT_AMD64 | 0x00000010)
CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT
CONTEXT_FULL_64 = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS |
                CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS_64)
CONTEXT_EXCEPTION_ACTIVE = 0x0000000008000000
CONTEXT_SERVICE_ACTIVE      = 0x0000000010000000
CONTEXT_EXCEPTION_REQUEST   = 0x0000000040000000
CONTEXT_EXCEPTION_REPORTING = 0x0000000080000000

class M128A(ctypes.Structure):
    _fields_ = [
            ("Low", DWORD64),
            ("High", DWORD64)
            ]
class PROCESSENTRY32(ctypes.Structure):
    _fields_ = [
        ('dwSize',              DWORD),
        ('cntUsage',            DWORD),
        ('th32ProcessID',       DWORD),
        ('th32DefaultHeapID',   ctypes.POINTER(DWORD)),
        ('th32ModuleID',        DWORD),
        ('cntThreads',          DWORD),
        ('th32ParentProcessID', DWORD),
        ('pcPriClassBase',      ctypes.c_long),
        ('dwFlags',             DWORD),
        ('szExeFile',           CHAR * 260)
    ]
class XMM_SAVE_AREA32(ctypes.Structure):
    _fields_ = [
                ('ControlWord', WORD),
                ('StatusWord', WORD),
                ('TagWord', BYTE),
                ('Reserved1', BYTE),
                ('ErrorOpcode', WORD),
                ('ErrorOffset', DWORD),
                ('ErrorSelector', WORD),
                ('Reserved2', WORD),
                ('DataOffset', DWORD),
                ('DataSelector', WORD),
                ('Reserved3', WORD),
                ('MxCsr', DWORD),
                ('MxCsr_Mask', DWORD),
                ('FloatRegisters', M128A * 8),
                ('XmmRegisters', M128A * 16),
                ('Reserved4', BYTE * 96)
                ]
class DUMMYSTRUCTNAME(ctypes.Structure):
    _fields_=[
              ("Header", M128A * 2),
              ("Legacy", M128A * 8),
              ("Xmm0", M128A),
              ("Xmm1", M128A),
              ("Xmm2", M128A),
              ("Xmm3", M128A),
              ("Xmm4", M128A),
              ("Xmm5", M128A),
              ("Xmm6", M128A),
              ("Xmm7", M128A),
              ("Xmm8", M128A),
              ("Xmm9", M128A),
              ("Xmm10", M128A),
              ("Xmm11", M128A),
              ("Xmm12", M128A),
              ("Xmm13", M128A),
              ("Xmm14", M128A),
              ("Xmm15", M128A)
              ]
class DUMMYUNIONNAME(ctypes.Union):
    _fields_=[
              ("FltSave", XMM_SAVE_AREA32),
              ("DummyStruct", DUMMYSTRUCTNAME)
              ]

class CONTEXT64(ctypes.Structure):
    arch = ARCH_AMD64

    _pack_ = 16
    _fields_ = [
                ("P1Home", DWORD64),
                ("P2Home", DWORD64),
                ("P3Home", DWORD64),
                ("P4Home", DWORD64),
                ("P5Home", DWORD64),
                ("P6Home", DWORD64),
                ("ContextFlags", DWORD),
                ("MxCsr", DWORD),
                ("SegCs", WORD),
                ("SegDs", WORD),
                ("SegEs", WORD),
                ("SegFs", WORD),
                ("SegGs", WORD),
                ("SegSs", WORD),
                ("EFlags", DWORD),
                ("Dr0", DWORD64),
                ("Dr1", DWORD64),
                ("Dr2", DWORD64),
                ("Dr3", DWORD64),
                ("Dr6", DWORD64),
                ("Dr7", DWORD64),
                ("Rax", DWORD64),
                ("Rcx", DWORD64),
                ("Rdx", DWORD64),
                ("Rbx", DWORD64),
                ("Rsp", DWORD64),
                ("Rbp", DWORD64),
                ("Rsi", DWORD64),
                ("Rdi", DWORD64),
                ("R8", DWORD64),
                ("R9", DWORD64),
                ("R10", DWORD64),
                ("R11", DWORD64),
                ("R12", DWORD64),
                ("R13", DWORD64),
                ("R14", DWORD64),
                ("R15", DWORD64),
                ("Rip", DWORD64),
                ("DebugControl", DWORD64),
                ("LastBranchToRip", DWORD64),
                ("LastBranchFromRip", DWORD64),
                ("LastExceptionToRip", DWORD64),
                ("LastExceptionFromRip", DWORD64),
                ("DUMMYUNIONNAME", DUMMYUNIONNAME),
                ("VectorRegister", M128A * 26),
                ("VectorControl", DWORD64)
    ]
#内存页执行权限
PAGE_EXECUTE_READWRITE = 0x00000040

#硬件断点的条件
HW_ACCESS = 0x00000003
HW_EXECUTE = 0x00000000
HW_WRITE = 0x00000001

#内存页权限常量,VirtualProtect()函数使用
#VirtualProtect()函数可以在进程的地址空间中修改任何已提交页的访问保护。 例如，进程可以分配读/写页来存储敏感数据，然后它可以将访问权限更改为只读或无访问权限以防止意外覆盖。
PAGE_NOACCESS = 0x00000001
PAGE_READONLY = 0x00000002
PAGE_READWRITE = 0x00000004
PAGE_WRITECOPY = 0x00000008
PAGE_EXECUTE = 0x00000010
PAGE_EXECUTE_READ = 0x00000020
PAGE_EXECUTE_READWRITE = 0x00000040
PAGE_EXECUTE_WRITECOPY = 0x00000080
PAGE_GUARD = 0x00000100
PAGE_NOCACHE = 0x00000200
PAGE_WRITECOMBINE = 0x00000400

#CreateProcessA()创建一个新进程及其主线程。 新进程在调用进程的安全上下文中运行。
#以下结构体信息用于lpStartupInfo参数，描述如何启动进程
class STARTUPINFO(ctypes.Structure):
    _fields_ = [
        ("cb", DWORD),
        ("lpReserved", LPTSTR),
        ("lpDesktop", LPTSTR),
        ("lpTitle", LPTSTR),
        ("dwX", DWORD),
        ("dwY", DWORD),
        ("dwXSize", DWORD),
        ("dwYSize", DWORD),
        ("dwXCountChars", DWORD),
        ("dwYCountChars", DWORD),
        ("dwFillAttribute", DWORD),
        ("dwFlags", DWORD),
        ("wShowWindow", WORD),
        ("cbReserved2", WORD),
        ("lpReserved2", LPBYTE),
        ("hStdInput", HANDLE),
        ("hStdOutput", HANDLE),
        ("hStdError", HANDLE),
    ]
#用于在目标进程hook后接收其消息
class PROCESS_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("hProcess", HANDLE),
        ("hThread", HANDLE),
        ("dwProcessId", DWORD),
        ("dwThreadId", DWORD),
    ]

class EXCEPTION_RECORD(ctypes.Structure):
    pass

EXCEPTION_RECORD._fields_ = [
    ("ExceptionCode", DWORD),
    ("ExceptionFlags", DWORD),
    ("ExceptionRecord", ctypes.POINTER(EXCEPTION_RECORD)),
    ("ExceptionAddress", PVOID),
    ("NumberParameters", DWORD),
    ("ExceptionInformation", UINT_PTR * 15),
]

class _EXCEPTION_RECORD(ctypes.Structure):
    _fields_ = [
        ("ExceptionCode", DWORD),
        ("ExceptionFlags", DWORD),
        ("ExceptionRecord", ctypes.POINTER(EXCEPTION_RECORD)),
        ("ExceptionAddress", PVOID),
        ("NumberParameters", DWORD),
        ("ExceptionInformation", UINT_PTR * 15),
    ]

# 异常信息
class EXCEPTION_DEBUG_INFO(ctypes.Structure):
    _fields_ = [
        ("ExceptionRecord", EXCEPTION_RECORD),
        ("dwFirstChance", DWORD),
    ]

# 调试事件联合体
class DEBUG_EVENT_UNION(ctypes.Union):
    _fields_ = [
        ("Exception", EXCEPTION_DEBUG_INFO),
        #        ("CreateThread",      CREATE_THREAD_DEBUG_INFO),
        #        ("CreateProcessInfo", CREATE_PROCESS_DEBUG_INFO),
        #        ("ExitThread",        EXIT_THREAD_DEBUG_INFO),
        #        ("ExitProcess",       EXIT_PROCESS_DEBUG_INFO),
        #        ("LoadDll",           LOAD_DLL_DEBUG_INFO),
        #        ("UnloadDll",         UNLOAD_DLL_DEBUG_INFO),
        #        ("DebugString",       OUTPUT_DEBUG_STRING_INFO),
        #        ("RipInfo",           RIP_INFO),
    ]

# 调试器捕获的事件消息
class DEBUG_EVENT(ctypes.Structure):
    _fields_ = [
        ("dwDebugEventCode", DWORD),
        ("dwProcessId", DWORD),
        ("dwThreadId", DWORD),
        ("u", DEBUG_EVENT_UNION),
    ]

# CONTEXT结构体使用
class FLOATING_SAVE_AREA(ctypes.Structure):
    _fields_ = [

        ("ControlWord", DWORD),
        ("StatusWord", DWORD),
        ("TagWord", DWORD),
        ("ErrorOffset", DWORD),
        ("ErrorSelector", DWORD),
        ("DataOffset", DWORD),
        ("DataSelector", DWORD),
        ("RegisterArea", BYTE * 80),
        ("Cr0NpxState", DWORD),
    ]

#GetThreadContext()获得全部上文信息的值
class CONTEXT(ctypes.Structure):
    _fields_ = [

        ("ContextFlags", DWORD),
        ("Dr0", DWORD),
        ("Dr1", DWORD),
        ("Dr2", DWORD),
        ("Dr3", DWORD),
        ("Dr6", DWORD),
        ("Dr7", DWORD),
        ("FloatSave", FLOATING_SAVE_AREA),
        ("SegGs", DWORD),
        ("SegFs", DWORD),
        ("SegEs", DWORD),
        ("SegDs", DWORD),
        ("Edi", DWORD),
        ("Esi", DWORD),
        ("Ebx", DWORD),
        ("Edx", DWORD),
        ("Ecx", DWORD),
        ("Eax", DWORD),
        ("Ebp", DWORD),
        ("Eip", DWORD),
        ("SegCs", DWORD),
        ("EFlags", DWORD),
        ("Esp", DWORD),
        ("SegSs", DWORD),
        ("ExtendedRegisters", BYTE * 512),
    ]

#描述枚举的所有系统线程
class THREADENTRY32(ctypes.Structure):
    _fields_ = [
        ("dwSize", DWORD),
        ("cntUsage", DWORD),
        ("th32ThreadID", DWORD),
        ("th32OwnerProcessID", DWORD),
        ("tpBasePri", DWORD),
        ("tpDeltaPri", DWORD),
        ("dwFlags", DWORD),
    ]

# SYSTEM_INFO_UNION包含的结构体
class PROC_STRUCT(ctypes.Structure):
    _fields_ = [
        ("wProcessorArchitecture", WORD),
        ("wReserved", WORD),
    ]


# SYSTEM_INFO联合体
class SYSTEM_INFO_UNION(ctypes.Union):
    _fields_ = [
        ("dwOemId", DWORD),
        ("sProcStruc", PROC_STRUCT),
    ]

#设置内存断点时用到的计算大小的参数
class SYSTEM_INFO(ctypes.Structure):
    _fields_ = [
        ("uSysInfo", SYSTEM_INFO_UNION),
        ("dwPageSize", DWORD),
        ("lpMinimumApplicationAddress", LPVOID),
        ("lpMaximumApplicationAddress", LPVOID),
        ("dwActiveProcessorMask", DWORD),
        ("dwNumberOfProcessors", DWORD),
        ("dwProcessorType", DWORD),
        ("dwAllocationGranularity", DWORD),
        ("wProcessorLevel", WORD),
        ("wProcessorRevision", WORD),
    ]

#包含进程内存信息的结构体,VirtualQuery()使用
#VirtualQuery() 在另一个进程的地址空间中检索有关页面范围的信息
class MEMORY_BASIC_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("BaseAddress", PVOID),
        ("AllocationBase", PVOID),
        ("AllocationProtect", DWORD),
        ("RegionSize", SIZE_T),
        ("State", DWORD),
        ("Protect", DWORD),
        ("Type", DWORD),
    ]
